package com.wei.czz.framework.admin.manager;

import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.enums.admin.userRole.RelationModeEnum;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.framework.admin.entity.RoleMenuEntity;
import com.wei.czz.framework.admin.service.RoleMenuService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-06-15 09:15:53
 * className: RoleMenuManager
 * version: 1.0
 * description:
 */
@Component
@AllArgsConstructor
public class RoleMenuManager {

    private static final Logger log = LoggerFactory.getLogger(RoleMenuManager.class);

    private final RoleMenuService roleMenuService;

    @Transactional
    public void updateRoleMenu(Long roleId, List<Long> menuIdList) {
        // 获取操作用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        Integer deleteStatus = null;
        if (menuIdList.isEmpty()) {
            deleteStatus = CommonEnum.ZERO.getValue();
        }

        /*
            获取角色关联菜单
         */
        List<RoleMenuEntity> roleMenuList = roleMenuService.findList(roleId, null, deleteStatus);

        List<RoleMenuEntity> haveDeleteList = new ArrayList<>();
        Map<Long, RoleMenuEntity> roleMenuMap = new HashMap<>();
        for (RoleMenuEntity roleMenu : roleMenuList) {
            if (CommonEnum.ONE.getValue().equals(roleMenu.getDeleteStatus())) {
                haveDeleteList.add(roleMenu);
                continue;
            }
            roleMenuMap.put(roleMenu.getMenuId(), roleMenu);
        }
        Iterator<RoleMenuEntity> roleMenuIterator = haveDeleteList.iterator();

        List<RoleMenuEntity> saveList = new ArrayList<>();
        List<RoleMenuEntity> updateList = new ArrayList<>();

        if (menuIdList.isEmpty()) {
            // 角色新关联菜单为空，角色已关联菜单不为空
            for (RoleMenuEntity roleMenu : roleMenuMap.values()) {
                RoleMenuEntity updateRoleMenu = new RoleMenuEntity();
                updateRoleMenu.setId(roleMenu.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateRoleMenu);
            }
        } else if (roleMenuMap.isEmpty()) {
            // 角色新关联菜单不为空，角色已关联菜单为空

            for (Long menuId : menuIdList) {
                // 角色新关联菜单
                if (roleMenuIterator.hasNext()) {
                    // 利用已删除的数据
                    RoleMenuEntity updateRoleMenu = roleMenuIterator.next();
                    updateRoleMenu.setRoleId(roleId)
                            .setMenuId(menuId)
                            .setRelationMode(RelationModeEnum.AUTH.getValue())
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateRoleMenu);
                } else {
                    // 新增数据
                    RoleMenuEntity saveRoleMenu = this.getRoleMenu(roleId, menuId, CommonEnum.ZERO.getValue(), userPo,
                            date);
                    saveList.add(saveRoleMenu);
                }
            }

        } else {
            // 角色新关联菜单不为空，角色已关联菜单不为空

            for (Long menuId : menuIdList) {
                RoleMenuEntity roleMenu = roleMenuMap.remove(menuId);
                if (Objects.nonNull(roleMenu)) {
                    log.debug("角色已关联该菜单。roleId={} menuId={}", roleId, menuId);
                    continue;
                }
                // 角色新关联菜单
                if (roleMenuIterator.hasNext()) {
                    // 利用已删除的数据
                    RoleMenuEntity updateRoleMenu = roleMenuIterator.next();
                    updateRoleMenu.setRoleId(roleId)
                            .setMenuId(menuId)
                            .setRelationMode(RelationModeEnum.AUTH.getValue())
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateRoleMenu);
                } else {
                    // 新增数据
                    RoleMenuEntity saveRoleMenu = this.getRoleMenu(roleId, menuId, CommonEnum.ZERO.getValue(), userPo,
                            date);
                    saveList.add(saveRoleMenu);
                }
            }
            // 遍历角色与菜单映射，剩余数据全部删除
            for (RoleMenuEntity roleMenu : roleMenuMap.values()) {
                RoleMenuEntity updateRoleMenu = new RoleMenuEntity();
                updateRoleMenu.setId(roleMenu.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateRoleMenu);
            }
        }

        if (!saveList.isEmpty()) {
            roleMenuService.batchSave(saveList);
        }
        if (!updateList.isEmpty()) {
            roleMenuService.batchUpdate(updateList);
        }
    }

    @Transactional
    public void updateMenuRole(Long menuId, List<Long> roleIdList) {
        // 获取操作用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        Integer deleteStatus = null;
        if (roleIdList.isEmpty()) {
            deleteStatus = CommonEnum.ZERO.getValue();
        }

        /*
            获取菜单关联角色
         */
        List<RoleMenuEntity> roleMenuList = roleMenuService.findList(null, menuId, deleteStatus);

        List<RoleMenuEntity> haveDeleteList = new ArrayList<>();
        Map<Long, RoleMenuEntity> roleMenuMap = new HashMap<>();
        for (RoleMenuEntity roleMenu : roleMenuList) {
            if (CommonEnum.ONE.getValue().equals(roleMenu.getDeleteStatus())) {
                haveDeleteList.add(roleMenu);
                continue;
            }
            roleMenuMap.put(roleMenu.getRoleId(), roleMenu);
        }
        Iterator<RoleMenuEntity> roleMenuIterator = haveDeleteList.iterator();

        List<RoleMenuEntity> saveList = new ArrayList<>();
        List<RoleMenuEntity> updateList = new ArrayList<>();

        if (roleIdList.isEmpty()) {
            // 菜单新关联角色为空，菜单已关联角色不为空
            for (RoleMenuEntity roleMenu : roleMenuMap.values()) {
                RoleMenuEntity updateRoleMenu = new RoleMenuEntity();
                updateRoleMenu.setId(roleMenu.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateRoleMenu);
            }
        } else if (roleMenuMap.isEmpty()) {
            // 菜单新关联角色不为空，菜单已关联角色为空

            for (Long roleId : roleIdList) {
                // 菜单新关联角色
                if (roleMenuIterator.hasNext()) {
                    // 利用已删除的数据
                    RoleMenuEntity updateRoleMenu = roleMenuIterator.next();
                    updateRoleMenu.setRoleId(roleId)
                            .setMenuId(menuId)
                            .setRelationMode(RelationModeEnum.AUTH.getValue())
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateRoleMenu);
                } else {
                    // 新增数据
                    RoleMenuEntity saveRoleMenu = this.getRoleMenu(roleId, menuId, CommonEnum.ZERO.getValue(), userPo,
                            date);
                    saveList.add(saveRoleMenu);
                }
            }

        } else {
            // 菜单新关联角色不为空，菜单已关联角色不为空

            for (Long roleId : roleIdList) {
                RoleMenuEntity roleMenu = roleMenuMap.remove(roleId);
                if (Objects.nonNull(roleMenu)) {
                    log.debug("菜单已关联该角色。roleId={} menuId={}", roleId, menuId);
                    continue;
                }
                // 角色新关联菜单
                if (roleMenuIterator.hasNext()) {
                    // 利用已删除的数据
                    RoleMenuEntity updateRoleMenu = roleMenuIterator.next();
                    updateRoleMenu.setRoleId(roleId)
                            .setMenuId(menuId)
                            .setRelationMode(RelationModeEnum.AUTH.getValue())
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateRoleMenu);
                } else {
                    // 新增数据
                    RoleMenuEntity saveRoleMenu = this.getRoleMenu(roleId, menuId, CommonEnum.ZERO.getValue(), userPo,
                            date);
                    saveList.add(saveRoleMenu);
                }
            }
            // 遍历角色与菜单映射，剩余数据全部删除
            for (RoleMenuEntity roleMenu : roleMenuMap.values()) {
                RoleMenuEntity updateRoleMenu = new RoleMenuEntity();
                updateRoleMenu.setId(roleMenu.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateRoleMenu);
            }
        }

        if (!saveList.isEmpty()) {
            roleMenuService.batchSave(saveList);
        }
        if (!updateList.isEmpty()) {
            roleMenuService.batchUpdate(updateList);
        }
    }

    /**
     * 获取角色与菜单关联对象
     * @param roleId    角色主键
     * @param menuId    菜单主键
     * @param optMode   操作方式
     * @param userPo    操作用户
     * @param date      日期对象
     * @return 角色与菜单关联对象
     */
    private RoleMenuEntity getRoleMenu(Long roleId, Long menuId, Integer optMode, UserPo userPo, Date date) {
        RoleMenuEntity roleMenu = new RoleMenuEntity();
        roleMenu.setRoleId(roleId)
                .setMenuId(menuId)
                .setRelationMode(optMode)
                .setDeleteStatus(CommonEnum.ZERO.getValue())
                .setUpdateTime(date)
                .setUpdateUser(StringUtils.EMPTY)
                .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                .setCreateTime(date)
                .setCreateUser(userPo.getUsername())
                .setCreateUserId(userPo.getUserId());
        return roleMenu;
    }

}
